
\chapter{Side effects}


A \iix{side-effect} is a change in the \ix{state} of a running {\bf T}
system, such as a change in the value stored in some location, or an
effect on the outside world.
\index{locations}

Many useful programs can be written which make no use of side-effects.
In principle, side-effects other than those controlling the outside world are
unnecessary.  However, side effects, when used carefully, can be used to
promote program modularity and readability.  In addition, they may be
necessary in a {\bf T} implementation to obtain efficient program
execution.

\section{Assignment}

\label{section:assignment}

{\bf T} provides several special forms which perform assignment to
{\it locations\/}.  A location is a place in which a value may be stored,
for example, a variable, or the car of a list, or a component of a
structure.  Locations are not objects {\it per se\/}, although
references to them may be obtained through the use of \iix{locatives}.


\index{SET@{\tt SET}}
{\mbox {\tt (SET {\it location new-value\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill Special form

\label{SET}
\begin{inset}{}

{\tt SET} is a generalized assignment operator.
It alters the location specified by {\it location\/} to hold {\it new-value\/}.
The value of any {\tt SET}-expression is the {\it new-value\/} thus stored.

If {\it location\/} is a symbol, then it names a variable which has been
previously bound by a {\tt LAMBDA} or an {\tt LSET} (or indirectly by
any form which does {\tt LAMBDA}-binding, such as {\tt LET}),
whose value is to be altered.
\begin{codexenv}
    \begin{tabular}{lll}
(SET X (LIST 1 2 3))  &$\Longrightarrow$\ &  (1 2 3) \\
X                     &$\Longrightarrow$\ &  (1 2 3)
\end{tabular}
    \end{codexenv}
{\it Location\/} may also have the syntax of a call to an {\it access-type\/}
procedure or operation such as {\tt CAR}.  (In this manual, these are
marked as {\it Settable\/}.)
\label{Settable}
\begin{codexenv}
    \begin{tabular}{lll}
(SET (CAR X) 'A)  &$\Longrightarrow$\ &  A \\
X                 &$\Longrightarrow$\ &  (A 2 3)
\end{tabular}
    \end{codexenv}

\begin{codexenv}
(SET ({\it proc arg$_{\hbox{1}}$\/} \ldots\  {\it arg$_{\hbox{n}}$\/}) {\it value\/}) \\
  $\equiv$  ((SETTER {\it proc\/}) {\it arg$_{\hbox{1}}$\/} \ldots\  {\it arg$_{\hbox{n}}$\/} value)
\end{codexenv}

It is an error to use a {\mbox {\tt SET}} form in a value requiring
position.  For example,

{\mbox {{\tt (SET (p x y \ldots\ ) val)}}}

is conceptually equivalent

{\tt \begin{tabbing}
(LAMBDA \= () \+ \\
  ((SETTER p) x y \ldots\  val) \\
  (RETURN))
\end{tabbing}}

where {\tt (RETURN)} invokes the calling continuation with
no arguments. For more information on {\mbox {\tt RETURN}} see section
\ref{RETURN}.

In {\bf T3.1} {\mbox {\tt SET}} will continue
to return the value being assigned to the location, but an
error will be signalled in the future.
\end{inset}

\index{SETTER@{\tt SETTER}}
{\mbox {\tt (SETTER {\it procedure\/}) $\longrightarrow$\  {\it procedure\/}}}
\hfill Operation

\begin{inset}{}

Given an access routine, {\tt SETTER} returns a corresponding alteration
routine.  {\mbox {\tt (SETTER CAR)}}, for example, evaluates to a primitive
procedure that takes two arguments, a list whose car is to be changed,
and a value to store in the car of the list.

See also {\tt DEFINE-SETTABLE-OPERATION}, page
\pageref{DEFINE-SETTABLE-OPERATION}.  \end{inset}

\index{SWAP@{\tt SWAP}}
{\mbox {\tt (SWAP {\it location new-value\/}) $\longrightarrow$\  {\it object\/}}}
\hfill Special form

\begin{inset}{}

This behaves the same as {\tt SET}, except that the value
returned is the old value found in {\it location\/},
rather than the {\it new-value\/}.  For example,
the following expression exchanges the values of the variables {\tt X} and
{\tt Y}:
\begin{codexenv}
(SET X (SWAP Y X))
\end{codexenv}
\end{inset}

\index{EXCHANGE@{\tt EXCHANGE}}
{\mbox {\tt (EXCHANGE {\it location1 location2\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill Special form

\begin{inset}{}

Exchanges the values in the two locations.
\end{inset}

\index{MODIFY@{\tt MODIFY}}
{\mbox {\tt (MODIFY {\it location procedure\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill Special form

\begin{inset}{}

Stores a value in the {\it location\/} which is obtained by applying {\it procedure\/}
to the old value in {\it location\/}.
\begin{codexenv}
(MODIFY {\it location\/} 1+)  $\equiv$  (INCREMENT {\it location\/})
\end{codexenv}

The value of the {\mbox {\tt MODIFY}} special form is undefined, and
it is an error to use a {\mbox {\tt MODIFY}} form in a value requiring
position.  In {\bf T3.1} {\mbox {\tt MODIFY}} will continue to return
a value.
\end{inset}

\index{MODIFY-LOCATION@{\tt MODIFY-LOCATION}}
{\mbox {\tt (MODIFY-LOCATION {\it location continuation\/}) $\longrightarrow$\  {\it object\/}}}
\hfill Special form

\begin{inset}{}

Calls {\it continuation\/}, which should be a procedure of two arguments,
passing it an access procedure
of no arguments, which fetches the value in {\it location\/};
and an update procedure of one argument, which will store a
new value in {\it location\/}.

{\tt MODIFY-LOCATION}'s purpose is to ensure that any subforms
of the form for {\it location\/} are evaluated only once.  For example,
{\tt \begin{tabbing}
(INCREMENT \= (CAR (HACK)) \\
  \> $\equiv$ \\
(MODIFY-LOCATION \= (CAR (HACK)) \\
                 \> (LAMBDA (FETCH STORE) (STORE (+ (FETCH) 1))))
\end{tabbing}}
In this expression, {\tt (HACK)} will be evaluated only once, whereas in the following
naive expansion
\begin{codexenv}
(SET (CAR (HACK)) (+ (CAR (HACK)) 1))
\end{codexenv}
it is evaluated twice, which is presumably neither necessary nor desirable.
During the expansion of {\tt MODIFY-LOCATION} forms extra temporary
variables are introduced, as needed, to account for this.

{\tt MODIFY-LOCATION} is useful in macro expansions,
although awkward when written directly.
Other ``modification'' forms such as {\tt PUSH}, {\tt MODIFY}, and {\tt SWAP}
are implementeded as macros in terms of the
{\tt MODIFY-LOCATION} special form.

For example, one might define a {\tt DOUBLE} macro, which multiplies by two the
value in a location, as follows:
{\tt \begin{tabbing}
(DEFINE-SYNTAX \= (DOUBLE FORM) \+ \\
  ` (MODIFY-LOCATION \\
     ,FORM \\
     (LAMBDA (FETCH STORE) (STORE (* (FETCH) 2))))) \- \\

(DOUBLE (CAR (HACK)))
\end{tabbing}}
\end{inset}

\section{Locatives}

\label{section:locatives}

{\it Locatives\/} in {\bf T} are similar to the {\it pointers\/} or
{\it references\/} of languages like C or Algol 68.

Locatives are obtained by evaluating {\tt LOCATIVE}-expressions.  The
value in the location they refer to may be fetched using the
{\tt CONTENTS} operation, and stored using {\tt SET}.

Objects which act as locatives may be created using {\tt OBJECT}, as long
as they handle the {\tt CONTENTS} and {\tt (SETTER CONTENTS)} operations
appropriately, and handle {\tt LOCATIVE?} by returning true.

\index{LOCATIVE@{\tt LOCATIVE}}
{\mbox {\tt (LOCATIVE {\it location\/}) $\longrightarrow$\  {\it locative\/}}}
\hfill Special form

\begin{inset}{}

Returns a locative which accesses the location specified by {\it location\/}.
{\it Location\/} receives similar treatment to the {\it location\/} position
in the {\tt SET} special form; it may refer to a variable, or to a
``field'' within some mutable structure, for example the car of a pair.

The following equivalence approximates the behavior of {\tt LOCATIVE}:
{\tt \begin{tabbing}
(LOCATIVE \= {\it location\/}) \\
  \> $\equiv$ \\
(OBJECT \= NIL \+ \\
        ((CONTENTS SELF) {\it location\/}) \\
        (((SETTER CONTENTS) SELF VALUE) (SET {\it location\/} VALUE)) \\
        ((LOCATIVE? SELF) T))
\end{tabbing}}
This is accurate if {\it location\/} is a variable, but if it is a call,
the subforms of the call are evaluated when the {\tt LOCATIVE}-expression
is evaluated, not when the contents of the locative are required.
For example,
{\tt \begin{tabbing}
(LOCATIVE \= (FOO (BAR BAZ))) \\
  \> $\equiv$ \\
(LET \= (\= (TEMP1 FOO) \+ \+ \\
      (TEMP2 (BAR BAZ))) \- \\
  (OBJECT \= NIL \+ \\
          ((CONTENTS SELF) (TEMP1 TEMP2)) \\
          (((SETTER CONTENTS) SELF VALUE) (SET (TEMP1 TEMP2) VALUE)) \\
          ((LOCATIVE? SELF) T)))
\end{tabbing}}
\end{inset}

\index{CONTENTS@{\tt CONTENTS}}
{\mbox {\tt (CONTENTS {\it locative\/}) $\longrightarrow$\  {\it object\/}}}
\hfill Settable operation

\begin{inset}{}

Dereferences (indirects through) the {\it locative\/}.
\begin{codexenv}
    \begin{tabular}{lll}
(LSET Z (LIST 'A 'B))                   &$\Longrightarrow$\ &  (A B) \\
(CONTENTS (LOCATIVE (CAR Z)))           &$\Longrightarrow$\ &  A \\
(SET (CONTENTS (LOCATIVE (CAR Z))) 'C)  &$\Longrightarrow$\ &  C \\
Z                                       &$\Longrightarrow$\ &  (C B) \\

(CONTENTS (LOCATIVE {\it location\/}))  &$\equiv$&  {\it location\/} \\
(SET (CONTENTS (LOCATIVE {\it location\/})) {\it value\/}  &$\equiv$&  (SET {\it location\/} {\it value\/})
\end{tabular}
    \end{codexenv}
\end{inset}

\index{LOCATIVE?@{\tt LOCATIVE?}}
{\mbox {\tt (LOCATIVE? {\it object\/}) $\longrightarrow$\  {\it boolean\/}}}
\hfill Type predicate operation

\begin{inset}{}
Returns true if {\it object\/} is a locative.
\end{inset}

\section{Dynamic state}

\label{section:dynamicState}
\index{dynamic state}

\index{BIND@{\tt BIND}}
{\mbox {\tt (BIND {\it specs\/} . {\it body\/}) $\longrightarrow$\  {\it value-of-body\/}}}
\hfill Special form

\begin{inset}{}

{\tt BIND} implements \ix{dynamic binding}.  Syntactically, it is similar
to {\tt LET}, but semantically it is completely different.  {\tt BIND}
operates by doing temporary assignments to locations, for example, to
bound variables.  Unlike {\tt LET}, it does not introduce a new lexical
binding contour.

Note that the use of the term {\it bind\/} in this context is
unrelated to its use elsewhere (for example, at the beginning of chapter
\ref{environments}).

Each {\it spec\/} should have the syntax
\begin{codexenv}
({\it location\/} {\it value\/})
\end{codexenv}
The value in each {\it location\/} is obtained and saved.
Each {\it location\/} is assigned the {\it value\/}, as with {\tt SET}.
The {\it body\/} expressions are evaluated and the value of the last
is saved.  The {\it locations\/} are then restored to their original
saved values.  The {\tt BIND}-expression finally yields the saved value
of the {\it body\/}.
\begin{codexenv}
(BIND (({\it location\/} {\it value\/})) . {\it body\/})
\end{codexenv}
is therefore similar to
{\tt \begin{tabbing}
(LET \= ((SAVED-VALUE {\it location\/})) \+ \\
  (SET {\it location\/} {\it value\/}) \\
  (BLOCK0 \= (BLOCK . {\it body\/}) \+ \\
          (SET {\it location\/} SAVED-VALUE)))
\end{tabbing}}
or
{\tt \begin{tabbing}
(LET \= ((SAVED-VALUE {\it location\/})) \+ \\
  (SET {\it location\/} {\it value\/}) \\
  (UNWIND-PROTECT \= (BLOCK . {\it body\/}) \+ \\
                  (SET {\it location\/} SAVED-VALUE)))
\end{tabbing}}
Examples:
\begin{codexenv}
(LSET A 1) \\
(DEFINE (F) (+ A 1)) \\
(F)                   $\Longrightarrow$\   2 \\
(LET  ((A 10)) (F))   $\Longrightarrow$\   2 \\
(BIND ((A 10)) (F))   $\Longrightarrow$\   11 \\

(LSET X (LIST 1 2 3)) \\
(BIND (((CAR X) 10)) \\
  (LSET Y (COPY-LIST X))) \\
X  $\Longrightarrow$\   (1 2 3) \\
Y  $\Longrightarrow$\   (10 2 3)
\end{codexenv}
The values in the {\it locations\/} are restored, even
if a throw out of {\it body\/} occurs (see {\tt CATCH}, page \pageref{CATCH}).
For example:
{\tt \begin{tabbing}
(LET \= ((A 10)) \+ \\
  (CATCH EP (BIND ((A 20)) (EP NIL))) \\
  A) \\
  $\Longrightarrow$\   10
\end{tabbing}}
Any {\it location\/} in a {\tt BIND}-form which is a variable name
should name a variable which has been previously bound
using, for example, {\tt LSET} or {\tt LET}.
\end{inset}

\index{UNWIND-PROTECT@{\tt UNWIND-PROTECT}}
{\mbox {\tt (UNWIND-PROTECT {\it form . unwind-forms\/}) $\longrightarrow$\  {\it value-of-form\/}}}
\hfill Special form

\label{UNWIND-PROTECT}
\begin{inset}{}

{\tt UNWIND-PROTECT} behaves nearly the same as {\tt BLOCK0}:
the {\it form\/} is evaluated, and the value is saved; the {\it unwind-forms\/}
are evaluated; and the {\tt UNWIND-PROTECT}-expression yields the (saved)
value of {\it form\/}.  However, unlike {\tt BLOCK0},
{\tt UNWIND-PROTECT} guarantees that
the {\it unwind-forms\/} will be evaluated,
even if a throw occurs
during the evaluation of {\it form\/}.

In the following example, the motor will be stopped even if {\tt DRILL-HOLE}
attempts to throw out of the {\tt UNWIND-PROTECT}.
{\tt \begin{tabbing}
(UNWIND-PROTECT \= (BLOCK \= (START-MOTOR) \+ \+ \\
                       (DRILL-HOLE)) \- \\
                (STOP-MOTOR)) \\
\end{tabbing}}

A throw (see page \pageref{CATCH}) out of the {\tt BLOCK} - for example,
as a result of calling {\tt DRILL-HOLE}, will evaluate the exit form
{\mbox {\tt (STOP-MOTOR)}} before control finally returns to its corresponding
{\tt CATCH}.

It is an error to throw out of the unwind forms of an {\tt UNWIND-PROTECT}.
\end{inset}

